﻿using BPanel.Core.Extensions;
using BPanel.Core.YidGenerator;
using FreeSql.Internal;

namespace BPanel.Web.Extensions;

public static class FreeSqlExtension
{
    /// <summary>
    /// 添加FreeSql
    /// </summary>
    /// <param name="serviceCollection"></param>
    /// <param name="configuration"></param>
    public static IServiceCollection AddFreeSqlData(this IServiceCollection serviceCollection, IConfiguration configuration)
    {
        var connectionString = configuration.GetValue<string>("ConnectionStrings:SqlConnection");

        serviceCollection.AddSingleton<IFreeSql>((Func<IServiceProvider, IFreeSql>)FreeSqlFactory);
        return serviceCollection;

        IFreeSql FreeSqlFactory(IServiceProvider r)
        {
            var freeSql = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.Sqlite, connectionString)
                .UseAutoSyncStructure(true) //自动同步实体结构到数据库，FreeSql不会扫描程序集，只有CRUD时才会生成表。
                .UseNameConvert(NameConvertType.PascalCaseToUnderscoreWithLower)
                .Build();
            return freeSql;
        }
    }

    /// <summary>
    /// 使用FreeSql同步数据库
    /// </summary>
    /// <param name="app"></param>
    public static async Task<WebApplication> UseFreeSqlData(this WebApplication app)
    {
        //在项目启动时，从容器中获取IFreeSql实例，并执行一些操作：同步表，种子数据,FluentAPI等
        using var serviceScope = app.Services.CreateScope();

        var freeSql = serviceScope.ServiceProvider.GetRequiredService<IFreeSql>();

        freeSql.CodeFirst.SyncStructure(typeof(BPanel.Database.Entities.System));
        freeSql.CodeFirst.SyncStructure(typeof(BPanel.Database.Entities.Database));
        freeSql.CodeFirst.SyncStructure(typeof(BPanel.Database.Entities.WebSite));
        freeSql.CodeFirst.SyncStructure(typeof(BPanel.Database.Entities.WebSiteDomain));
        freeSql.CodeFirst.SyncStructure(typeof(BPanel.Database.Entities.WebSiteFtp));
        freeSql.CodeFirst.SyncStructure(typeof(BPanel.Database.Entities.PhpVersion));

        if (!await freeSql.Select<BPanel.Database.Entities.System>().Where(c => c.Username == "admin").AnyAsync())
        {
            await freeSql.Insert(new BPanel.Database.Entities.System()
            {
                Id = Yid.NewId(),
                Username = "admin",
                Password = "123456".Md5(),
                DefaultSiteDirectory = "/www/root",
                ErrorCount = 0,
                LockTime = DateTime.MinValue,
                Port = 9999,
                Title = "BPanel面板",
                Version = "0.0.1"
            }).ExecuteAffrowsAsync();
        }

        return app;
    }
}